/*
 * flash.c
 *
 *  Created on: 2020年7月13日
 *      Author: armwnid
 */
#include "common.h"
#include "log.h"

//如果日志等级大于LOG_DEBUG，则会打印该日志，反之不会。
#define LOG_LOCAL_LEVEL LOG_DEBUG
#define TAG  "FLASH:"

#if 0
sector_cell_t sector_table[] = {
    {0x08000000, 0x4000, FLASH_Sector_0},   /*SECTOR 0 16KB*/
    {0x08004000, 0x4000, FLASH_Sector_1},   /*SECTOR 1 16KB*/
    {0x08008000, 0x4000, FLASH_Sector_2},   /*SECTOR 2 16KB*/
    {0x0800C000, 0x4000, FLASH_Sector_3},   /*SECTOR 3 16KB*/
    {0x08010000, 0x10000, FLASH_Sector_4},  /*SECTOR 4 64KB*/
    {0x08020000, 0x20000, FLASH_Sector_5},  /*SECTOR 5 128KB*/
    {0x08040000, 0x20000, FLASH_Sector_6},  /*SECTOR 6 128KB*/
    {0x08060000, 0x20000, FLASH_Sector_7},  /*SECTOR 7 128KB*/
    {0x08080000, 0x20000, FLASH_Sector_8},  /*SECTOR 8 128KB*/
    {0x080A0000, 0x20000, FLASH_Sector_9},  /*SECTOR 9 128KB*/
    {0x080C0000, 0x20000, FLASH_Sector_10},  /*SECTOR 10 128KB*/
    {0x080E0000, 0x20000, FLASH_Sector_11},  /*SECTOR 11 128KB*/
};
/*******************************************************************************
* Function Name  : flash_sector_offset
* Description    : Calculate the offset of sectors
* Input          : - Size: The image size
*                  - isp_base_addr: the address system saved.
* Output         : None
* Return         : The number of pages
*******************************************************************************/
flash_sec_info_t flash_sector_offset(u32 Size, u32 isp_base_addr)
{
  u32 i = 0;
  flash_sec_info_t search_result = {0};

  u32 sec_count = sizeof(sector_table)/sizeof(sector_cell_t);
  LOGD("total sector count:%d,firmware size:%d", sec_count, Size);

  for (i = 0; i < sec_count; i++) {
    if (sector_table[i].addr <= isp_base_addr && isp_base_addr < sector_table[i+1].addr ) {
        //½ö½öÊÇÔÚµÚÒ»´Î±È½ÏÊ±¾ÍÂú×ãÌõ¼þ
        if (!search_result.sec_cout) {
            search_result.start_sec_num = i;
            search_result.sec_cout++;
            if (sector_table[i].len >= Size)
                return search_result;
            Size -= sector_table[i].len;
            continue;
        }
        if (sector_table[i].len <= Size) {
            search_result.sec_cout++;
            Size -= sector_table[i].len;
            continue;
        } else {
            search_result.sec_cout++;
            break;
        }
    }
    //this last sector
    if ((i == sec_count - 1) && (sector_table[i].addr <= isp_base_addr) && (sector_table[i].len >= Size)) {
        LOGI("this is last sector, sec_count:%d", sec_count);
        search_result.start_sec_num = i;
        search_result.sec_cout++;
    }
  }

  return search_result;
}
#endif

/**
  * @brief  测试flash的写入是否正常
  * @param
  *          - flash_addr:写入flash地址
  *          - w_dat：要写入的数据
  * @retval None
  */
void write_flash_data_test(uint32_t flash_addr,uint32_t w_dat)
{
    FLASH_Unlock();//解锁FLASH准备写入
    //清楚一些flash状态标记，确保flash在一个良好的状态
    FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR);
    //擦除当前地址所对应的页，注意这里不用页对齐
    if (FLASH_ErasePage(flash_addr)!= FLASH_COMPLETE) {
        while (1) {
                LOGE("erase page error, addr:0x%d",flash_addr);
        }
    }
    //对flash写入一个字32bit
    if (FLASH_ProgramWord(flash_addr, w_dat) == FLASH_COMPLETE) {
            LOGI("write data 0x%x success!,addr:0x%x",w_dat,flash_addr);
    } else {
            LOGE("write data 0x%x failed,addr:0x%x",w_dat,flash_addr);
    }
    //锁住flash保证不被任意串改
    FLASH_Lock();
    //测试数据的有效性
    if (w_dat == *(__IO uint32_t *)flash_addr) {
        LOGI("flash test ok!");
    } else {
        LOGE("flash test failed!");
    }
}
